﻿using System;
using System.Collections.ObjectModel;
using System.Text;
using Unknown.Framework.Develop;
using Unknown.Framework.General;
using Unknown.Source.Entity.Coder;
using Unknown.Source.Entity.NormalView;

namespace Unknown.Source.Business.Coder
{
    /// <summary>
    /// 类描述处理类
    /// </summary>
    public static class ClassDescribeHandler
    {
        /// <summary>
        /// 默认命名空间前缀
        /// </summary>
        public const string DefaultNamespacePrefix = "Normal";

        /// <summary>
        /// 分割
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="separator">分隔符</param>
        /// <returns>结果</returns>
        public static string[] Split(string value, string separator)
        {
            string[] results = null;

            if ((!string.IsNullOrEmpty(value)) && (!string.IsNullOrEmpty(separator)))
            {
                try
                {
                    results = value.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
                }
                catch (ArgumentException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(separator);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
            }

            return results;
        }

        /// <summary>
        /// 构建属性描述
        /// </summary>
        /// <param name="codeConfiguration">代码配置</param>
        /// <param name="column">字段</param>
        /// <param name="dataTypeHandler">数据类型处理</param>
        /// <returns>结果</returns>
        public static PropertyDescribe BuildPropertyDescribe(CodeConfiguration codeConfiguration, Column column, IDataTypeHandler dataTypeHandler)
        {
            PropertyDescribe result = new PropertyDescribe();

            if ((codeConfiguration != null) && (column != null) && (dataTypeHandler != null))
            {
                StringBuilder nameBuilder = new StringBuilder();
                StringBuilder parameterBuilder = new StringBuilder();
                string[] names = ClassDescribeHandler.Split(column.Name, codeConfiguration.Separator);
                if (names != null)
                {
                    bool first = true;
                    foreach (string name in names)
                    {
                        string lowerValue = name.ToLower(Variable.Culture);
                        bool nameUpper = true;
                        bool parameterUpper = true;

                        if (first)
                        {
                            parameterUpper = false;
                            first = false;
                        }

                        foreach (char c in lowerValue)
                        {
                            if (nameUpper)
                            {
                                nameBuilder.Append(char.ToUpper(c, Variable.Culture));
                                nameUpper = false;
                            }
                            else
                            {
                                nameBuilder.Append(c);
                            }

                            if (parameterUpper)
                            {
                                parameterBuilder.Append(char.ToUpper(c, Variable.Culture));
                                parameterUpper = false;
                            }
                            else
                            {
                                parameterBuilder.Append(c);
                            }
                        }
                    }
                }

                result.Name = nameBuilder.ToString();
                result.Parameter = parameterBuilder.ToString();
                result.DataType = dataTypeHandler.BuildDataType(column);
                result.Assign = dataTypeHandler.BuildAssign(column);
                result.DefaultValue = dataTypeHandler.BuildDefaultValue(column);
                result.DatabaseType = dataTypeHandler.BuildDatabaseType(column);

                result.Constant = false;
                foreach (string constant in codeConfiguration.Constants)
                {
                    if (constant == result.Name)
                    {
                        result.Constant = true;
                        break;
                    }
                }

                result.Column = column;
            }

            return result;
        }

        /// <summary>
        /// 构建
        /// </summary>
        /// <param name="cascadeTable">级联表</param>
        /// <param name="codeConfiguration">代码配置</param>
        /// <param name="dataTypeHandler">数据类型处理</param>
        /// <returns>结果</returns>
        public static ClassDescribe Build(CascadeTable cascadeTable, CodeConfiguration codeConfiguration, IDataTypeHandler dataTypeHandler)
        {
            ClassDescribe result = new ClassDescribe();

            if ((cascadeTable != null) && (codeConfiguration != null) && (dataTypeHandler != null))
            {
                StringBuilder nameBuilder = new StringBuilder();
                string[] names = ClassDescribeHandler.Split(cascadeTable.Table.Name, codeConfiguration.Separator);

                result.NamespaceMap = ClassDescribeHandler.DefaultNamespacePrefix;
                if (names.Length == 1)
                {
                    names = new string[] { string.Empty, names[0] };
                }

                bool first = true;
                foreach (string name in names)
                {
                    string nameLower = name.ToLower(Variable.Culture);
                    if (first)
                    {
                        foreach (NamespaceMap namespaceMap in codeConfiguration.NamespaceMaps)
                        {
                            if (nameLower == namespaceMap.Source.ToLower(Variable.Culture))
                            {
                                result.NamespaceMap = namespaceMap.Target;
                                break;
                            }
                        }
                        first = false;
                    }
                    else
                    {
                        bool upper = true;
                        foreach (char c in nameLower)
                        {
                            if (upper)
                            {
                                nameBuilder.Append(char.ToUpper(c, Variable.Culture));
                                upper = false;
                            }
                            else
                            {
                                nameBuilder.Append(c);
                            }
                        }
                    }
                }

                result.Name = nameBuilder.ToString();
                result.Table = cascadeTable.Table;
                foreach (Column column in cascadeTable.Columns)
                {
                    PropertyDescribe propertyDescribe = ClassDescribeHandler.BuildPropertyDescribe(codeConfiguration, column, dataTypeHandler);
                    if (propertyDescribe.Name == codeConfiguration.PrimaryKey)
                    {
                        result.PrimaryKeyPropertyDescribe = propertyDescribe;
                    }
                    result.PropertyDescribes.Add(propertyDescribe);
                }
            }

            return result;
        }
    }
}
